10. Dynamic Proxy
Dynamic Proxy
In this lesson, you'll learn the basics of using dynamic proxies in Java.
ND079 JPND C2 L04 A09 Dynamic Proxy
What is a Dynamic Proxy?
A dynamic proxy is a class that implements a list of interfaces specified at runtime.
When you write a class to implement an interface statically, you need to know at compile-time what interfaces you're going to implement.
By contrast, if you use a dynamic proxy, you don't need to know at compile-time what interfaces will be implemented. This is all determined at runtime. This is what makes dynamic proxies "dynamic".
How Do Dynamic Proxies Work?
First, you create a custom
InvocationHandler
.InvocationHandler
is an abstract class that receives method invocations. A method invocation is aMethod
and an array of parameters.Then, you create a dynamic proxy instance using the
Proxy.newProxyInstance()
).When clients call a method on the proxy instance, the method invocation is forwared to your
MethodInvocationHandler
.
SOLUTION:
- Creating method interceptors, such as for Aspect Oriented Programming.
- Creating a general Decorator wrapper so that you do not need to now the interface being wrapped at compile-time.
Dynamic Proxy Demo
ND079 JPND C2 L04 A10 Demo Dynamic Proxy
Code from the Demo
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashSet;
import java.util.Set;
public final class LoggingProxy {
public static void main(String[] args) {
Set<String> targetSet = new HashSet<>();
Object proxy = Proxy.newProxyInstance(
LoggingProxy.class.getClassLoader(),
new Class[]{Set.class},
new LoggingInvocationHandler(targetSet));
Set<String> loggedSet = (Set<String>) proxy;
loggedSet.add("item");
System.out.println(targetSet.contains("item"));
}
static class LoggingInvocationHandler implements InvocationHandler {
private final Object targetObject;
public LoggingInvocationHandler(Object targetObject) {
this.targetObject = targetObject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(targetObject.getClass() + "." + method.getName() + "()");
return method.invoke(targetObject, args);
}
}
}